package com.e3.toolkit;

import java.io.Serializable;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;

public class TableMeta implements Serializable {

	private static final long serialVersionUID = -2085829751348629065L;
	
	private String tableName;
	
	private boolean isOCEntity = false;
	
	private boolean isBillEntity = false;
			
	private List<ColumnMeta> colMetas = new ArrayList<ColumnMeta>();

	public TableMeta(String tableName){
		this.tableName = tableName;
	}
	
	public String getTableName() {
		return tableName;
	}

	public void setTableName(String tableName) {
		this.tableName = tableName;
	}
	
	public String getTemTableName() {
		return tableName+"_N";
	}

	public boolean isOCEntity() {
		return isOCEntity;
	}

	public void setOCEntity(boolean isOCEntity) {
		this.isOCEntity = isOCEntity;
	}

	public boolean isBillEntity() {
		return isBillEntity;
	}

	public void setBillEntity(boolean isBillEntity) {
		this.isBillEntity = isBillEntity;
	}

	public ColumnMeta createColMeta(){
		ColumnMeta colMeta = new ColumnMeta();
		colMetas.add(colMeta);
		return colMeta;
	}

	public List<ColumnMeta> getColMetas() {
		return colMetas;
	}

	public void setColMetas(List<ColumnMeta> colMetas) {
		this.colMetas = colMetas;
	}

	public boolean equals(Object o){
		if(!(o instanceof TableMeta)){
			return false;
		}
		
		TableMeta cm = (TableMeta)o;
		if(this.getTableName().equals(cm.getTableName())){
			return true;
		}
		
		return false;
	}
	
	public String toString(){
		return tableName;
	}
	
	public void setPrimaryKey(String name){
		for(ColumnMeta meta:colMetas){
			if(meta.getColName().equalsIgnoreCase(name)){
				meta.setPrimaryKey(true);
				break;
			}
		}
	}
	
	public String getPrimaryKey(){
		for(ColumnMeta meta:colMetas){
			if(meta.isPrimaryKey()){
				return meta.getColName();
			}
		}
		return "ID";
	}
	
	public class ColumnMeta implements Serializable {
		private static final long serialVersionUID = 954948875762783613L;
		
		private String colName; 
		
		private String dataTypeName;
		
		private int dataType;
		
		private boolean isPrimaryKey = false;
		
		private boolean isNullable = true;
		
		private int length;
		
		private int digits; 

		public String getColName() {
			return colName;
		}

		public void setColName(String colName) {
			this.colName = colName;
		}

		public String getDataTypeName() {
			return dataTypeName;
		}

		public void setDataTypeName(String dataTypeName) {
			this.dataTypeName = dataTypeName;
		}

		public int getDataType() {
			return dataType;
		}

		public void setDataType(int dataType) {
			this.dataType = dataType;
		}

		public boolean isPrimaryKey() {
			return isPrimaryKey;
		}

		public void setPrimaryKey(boolean isPrimaryKey) {
			this.isPrimaryKey = isPrimaryKey;
		}

		public boolean isNullable() {
			return isNullable;
		}

		public void setNullable(boolean isNullable) {
			this.isNullable = isNullable;
		}

		public int getLength() {
			return length;
		}

		public void setLength(int length) {
			this.length = length;
		}

		public int getDigits() {
			return digits;
		}

		public void setDigits(int digits) {
			this.digits = digits;
		}
		
		public String isPrimaryKeyToString(){
			return String.valueOf(isPrimaryKey);
		}
		
		public String isNullableToString(){
			return String.valueOf(isNullable);
		}

		public boolean equals(Object o){
			if(!(o instanceof ColumnMeta)){
				return false;
			}
			
			ColumnMeta cm = (ColumnMeta)o;
			if(this.getColName().equals(cm.getColName())){
				return true;
			}
			
			return false;
		}
	}
	public String getFieldNameList(){
		StringBuffer s = new StringBuffer();
		for (ColumnMeta field : colMetas) {
			s.append(field.getColName().toUpperCase()+",");
		}
		String str = s.toString();
		str = str.substring(0,str.length()-1);
		return str;
	}
	public String getJavaTypeName(ColumnMeta field){
		int type = field.getDataType();
		String className = "String";
		switch(type){
        case Types.NUMERIC:
        	className = "Integer";
        	if(field.getDigits()>0){
        		className = "Double";
        	}
        	else if(field.getLength()==1){
        		className = "Boolean";
        	}
        	else if(field.getLength()>20){
        		className = "Long";
        	}
        	break;
        case Types.DECIMAL:
        	className = "Integer";
        	if(field.getDigits()>0){
        		className = "Double";
        	}
        	else if(field.getLength()>20){
        		className = "Long";
        	}
            break;

        case Types.BIT:			
            className = "Boolean";
            break;

        case Types.TINYINT:
            className = "Boolean";
            break;

        case Types.SMALLINT:
            className = "Integer";
            break;

        case Types.INTEGER:
            className = "Integer";
            break;

        case Types.BIGINT:
            className = "Long";
            break;

        case Types.REAL:
            className = "Float";
            break;

        case Types.FLOAT:
        	className = "Float";
        	break;
        case Types.DOUBLE:
        	className = "Double";
            break;
			
        case Types.BINARY:
        case Types.VARBINARY:
        case Types.LONGVARBINARY:

        case Types.DATE:
        	className = "java.util.Date";
            break;

        case Types.TIME:
        	className = "java.util.Date";
            break;
            
        case Types.TIMESTAMP:
        	className = "java.util.Date";
            break;
            
        case Types.BLOB:
            className = "byte[]";
            break;

        case Types.CLOB:
        	className = "String";
        	break;
        }
        
        return className;

	}
	
	
	public String getJavaFieldName(ColumnMeta field){
		String name = field.getColName();
		
		return firstCharToUpper(name);
	}
	
	public String getSetterMethod(ColumnMeta field){
		String jfName = getJavaFieldName(field);
		char c = jfName.charAt(0);
		String name = String.valueOf(Character.toUpperCase(c))+jfName.substring(1);
		
		return "set"+name;
	}
	
	public String getGetterMethod(ColumnMeta field){
		String jfName = getJavaFieldName(field);
		char c = jfName.charAt(0);
		String name = String.valueOf(Character.toUpperCase(c))+jfName.substring(1);
		if(getJavaTypeName(field).equals("boolean")){
			return "is"+name;
		}
		return "get"+name;
	}
	
	public String getClassName(){
		String name = tableName.substring(tableName.lastIndexOf("_"));
		name = firstCharToUpper(name);
		name = String.valueOf(Character.toUpperCase(name.charAt(0)))+name.substring(1);
		return name;
	}
	private String firstCharToUpper(String name){
		StringBuffer sb = new StringBuffer();
		char[] cs = name.toCharArray();
		boolean toUpper = false;
		for (char c : cs) {
			if('_' == c){
				toUpper = true;
				continue;
			}
			if(toUpper){
				sb.append(String.valueOf(c).toUpperCase());
				toUpper = false;
			}
			else{
				sb.append(c);
			}
		}
		return sb.toString();
	}
}
